package com.ruoyi.quartz.task;

import com.ruoyi.api.domain.recipe.DishDetailEntity;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.file.MimeTypeUtils;
import com.ruoyi.recipe.domain.RecipeDish;
import com.ruoyi.recipe.domain.RecipeDishStep;
import com.ruoyi.recipe.domain.RecipeImageSync;
import com.ruoyi.recipe.service.IRecipeDishService;
import com.ruoyi.recipe.service.IRecipeDishStepService;
import com.ruoyi.recipe.service.IRecipeImageSyncService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

@Component("classifyImageTask")
public class ClassifyImageTask extends BaseTask {

    @Autowired
    private IRecipeDishService recipeDishService;

    @Autowired
    private IRecipeDishStepService recipeDishStepService;

    @Autowired
    private IRecipeImageSyncService recipeImageSyncService;

    private final Map<String, DishDetailEntity> dishMap = new ConcurrentHashMap<>();

    private String CURRENT_YEAR;

    private String CURRENT_MONTH;

    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
    private final List<CompletableFuture<Void>> futures = new ArrayList<>();

    public void runTask() {
        try {
            String uploadPath = RuoYiConfig.getUploadPath();
            File directory = new File(uploadPath, "recipe");
            if (!directory.exists() || !directory.isDirectory()) {
                throw new RuntimeException("目录不存在或不是目录：" + directory.getAbsolutePath());
            }

            setYearAndMonth();

            // 使用线程池处理文件
            processTaskConcurrent(directory);

            // 等待所有任务完成
            CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();

            log.info("图片绑定任务完成，共处理{}个文件", futures.size());

            // 在所有任务完成后删除空文件夹
            deleteEmptyDirectories(directory);
        } catch (Exception e) {
            log.error("ClassifyImageTask任务执行出错：", e);
        } finally {
            futures.clear();
        }
    }

    private void deleteEmptyDirectories(File directory) {
        if (directory == null || !directory.exists() || !directory.isDirectory()) {
            return;
        }

        File[] files = directory.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    deleteEmptyDirectories(file);
                }
            }
        }

        // 删除空文件夹
        if (directory.listFiles() != null && directory.listFiles().length == 0) {
            if (directory.delete()) {
                log.info("删除空文件夹：{}", directory.getAbsolutePath());
            }
        }
    }

    private void processTaskConcurrent(File file) {
        if (file == null || !file.exists() || file.isHidden()) {
            return;
        }

        if (file.isDirectory()) {
            File[] files = file.listFiles();
            if (files != null && files.length > 0) {
                for (File f : files) {
                    processTaskConcurrent(f);
                }
            }
        } else {
            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                try {
                    processFile(file);
                } catch (IOException e) {
                    log.error("文件处理失败：" + file.getAbsolutePath(), e);
                }
            }, threadPoolTaskExecutor).exceptionally(ex -> {
                log.error("异步任务执行失败", ex);
                return null;
            });

            futures.add(future);
        }
    }

    private void processTask(File file) throws IOException {
        if (file == null || !file.exists() || file.isHidden()) {
            return;
        }

        if (file.isDirectory()) {
            File[] files = file.listFiles();
            if (files != null && files.length > 0) {
                for (File f : files) {
                    processTask(f);
                }
            } else {
                file.delete();
            }
            if (file.exists()) {
                file.delete();
            }
        } else {
            processFile(file);
        }
    }

    private void processFile(File file) throws IOException {
        if (!isImage(file.getName())) {
            return;
        }

        String fileName = file.getName();
        if (fileName.lastIndexOf("-") <= 0 || fileName.lastIndexOf(".") <= 2) {
            log.info("文件名格式不正确：" + fileName);
            return;
        }

        String stepSortStr = fileName.substring(fileName.lastIndexOf("-") + 1, fileName.lastIndexOf("."));
        if (!stepSortStr.matches("^\\d+$")) {
            log.info("文件名格式不正确：" + fileName);
            return;
        }

        int stepSort = Integer.parseInt(stepSortStr);
        DishDetailEntity dishDetailEntity = dishMap.computeIfAbsent(file.getParentFile().getName(), k -> {
            RecipeDish dishQueryEntity = new RecipeDish();
            dishQueryEntity.setDishCode(k);
            List<RecipeDish> dishList = recipeDishService.selectRecipeDishList(dishQueryEntity);
            if (dishList == null || dishList.isEmpty()) {
                log.info("菜品不存在：" + k);
                return null;
            }

            DishDetailEntity entity = new DishDetailEntity();
            BeanUtils.copyBeanProp(entity, dishList.get(0));
            RecipeDishStep stepQueryEntity = new RecipeDishStep();
            stepQueryEntity.setDishId(dishList.get(0).getDishId());
            List<RecipeDishStep> stepList = recipeDishStepService.selectRecipeDishStepList(stepQueryEntity);
            if (stepList == null || stepList.isEmpty()) {
                log.info("菜品步骤不存在：" + k);
                return null;
            }
            entity.setBuZhou(stepList);
            return entity;
        });

        if (dishDetailEntity == null) {
            return;
        }

        RecipeDishStep step = dishDetailEntity.getBuZhou().stream()
                .filter(s -> s.getStepSort() == stepSort)
                .findFirst()
                .orElse(null);

        if (step == null) {
            log.info("步骤不存在：" + file.getParentFile().getName() + " - " + stepSort);
            return;
        }

        String targetPathStr = RuoYiConfig.getUploadPath() + "/" + CURRENT_YEAR + "/" + CURRENT_MONTH + "/recipe";
        File targetPath = new File(targetPathStr);
        ensureDirectory(targetPath);

        File targetFile = new File(targetPath, file.getName());
        log.info("文件移动：" + file.getAbsolutePath() + " -> " + targetFile.getAbsolutePath());
        Files.move(file.toPath(), targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING);

        updateRecipeDishStep(step, targetFile);
        updateRecipeDish(dishDetailEntity, step, targetFile);

//        RecipeImageSync sync = new RecipeImageSync();
//        sync.setFileName(file.getName());
//        sync.setFilePath(targetFile.getAbsolutePath());
//        sync.setDishId(dishDetailEntity.getDishId());
//        sync.setDishCode(file.getParentFile().getName());
//        sync.setDishName(dishDetailEntity.getDishName());
//        sync.setSuccess("1");
//        recipeImageSyncService.insertRecipeImageSync(sync);
    }

    private void ensureDirectory(File directory) throws IOException {
        if (!directory.exists() && !directory.mkdirs()) {
            throw new IOException("创建目录失败：" + directory.getAbsolutePath());
        }
    }

    private void updateRecipeDishStep(RecipeDishStep step, File targetFile) {
        RecipeDishStep stepEntity = new RecipeDishStep();
        stepEntity.setStepId(step.getStepId());
        stepEntity.setStepPic("/profile/upload/" + CURRENT_YEAR + "/" + CURRENT_MONTH + "/recipe/" + targetFile.getName());
        recipeDishStepService.updateRecipeDishStep(stepEntity);
    }

    private void updateRecipeDish(DishDetailEntity dishDetailEntity, RecipeDishStep step, File targetFile) {
        if (step.getStepSort() == dishDetailEntity.getBuZhou().size()) {
            RecipeDish dishEntity = new RecipeDish();
            dishEntity.setDishId(dishDetailEntity.getDishId());
            dishEntity.setDishPic("/profile/upload/" + CURRENT_YEAR + "/" + CURRENT_MONTH + "/recipe/" + targetFile.getName());
            recipeDishService.updateRecipeDish(dishEntity);
        }
    }

    private String getExtension(String fileName) {
        return fileName.substring(fileName.lastIndexOf(".") + 1);
    }

    private boolean isImage(String fileName) {
        String fileExt = getExtension(fileName);
        if (StringUtils.isEmpty(fileExt)) {
            return false;
        }
        return Arrays.stream(MimeTypeUtils.IMAGE_EXTENSION).anyMatch(str -> str.equalsIgnoreCase(fileExt));
    }

    private void setYearAndMonth() {
        // 获取当前日期
        LocalDate currentDate = LocalDate.now();

        // 创建一个DateTimeFormatter，格式为4位年份
        DateTimeFormatter yearFormatter = DateTimeFormatter.ofPattern("yyyy");
        // 创建一个DateTimeFormatter，格式为2位月份
        DateTimeFormatter monthFormatter = DateTimeFormatter.ofPattern("MM");

        // 使用formatter格式化当前日期
        CURRENT_YEAR = currentDate.format(yearFormatter);
        CURRENT_MONTH = currentDate.format(monthFormatter);
    }
}
